Lookerのキャッシュをきちんと理解する #looker
Lookerではデータベースのパフォーマンスを維持するためにキャッシュポリシーを設定できます。
今回はLookerにおけるキャッシュの仕組みをおさらいします。
キャッシュって?
直近のデータを、すぐまた必要になったときにいちいち本来の場所まで取りに行かないでいいように、すぐに取り出せるところに置いておくことです。(ざっくり)
Lookerにおけるキャッシュ
Lookerではクエリが実行されたときにデータベースに直ぐに問い合わせるのではなく、まずはLooker内のキャッシュを確認して以前全く同じクエリが投げられていないかを確認します。
キャッシュにそのクエリがないことを確認して初めてLookerはデータベースにクエリを投げます。
キャッシュについて何も設定していない状態、つまり、デフォルトの状態でもLookerはキャッシュを1時間保持します。そのため、明示的にキャッシングポリシーを設定していなくても、クエリが実行されたらLookerはまずキャッシュを確認します。
キャッシングポリシーの設定
それでは、個別にキャッシュポリシーを設定する方法をご紹介します。
datagroup
というパラメータでキャッシングポリシーを設定して、persist_for
というパラメータでモデルやExploreにdatagroup
で設定したキャッシングポリシーを適用します。
datagroupの設定
キャッシングポリシーを設定する単位は、モデル単位かExplore単位です。そのため、キャッシングポリシーを定義するdatagroup
パラメータはモデルファイルに定義します。
# modelファイル datagroup: datagroup_name { sql_trigger: SELECT MAX(id) FROM table;; max_cache_age: "24 hours" }
datagroup
パラメータには主に2つのサブパラメータを定義できます。2つのうちどちらかのサブパラメータを定義するだけでもきちんと動きますが、2つどちらも設定することを推奨しています。
sql_trigger
sql_trigger
パラメータはdatagroup
のサブパラメータのひとつです。
SELECT MAX(id) FROM table
のように1行1列を返すSQL文を定義します。
sql_trigger
で設定したSQLを、Looker側で定期的にデータベースに対してクエリを投げて、返ってきた値が前回と変わっているかどうかを確認します。そして、値が前回を変わっていた場合、そのデータグループは引き金が引かれた状態(triggered state)となり、キャッシュに保存されているクエリ結果を無効化します。
下記公式ページでは、sql_trigger
で使えるSQLの例が紹介されています。トリガーをテーブルの値ではなく、時間で指定する方法などが紹介されてるので参考にしてみてください。
また、sql_trigger
で指定したSQLをデータベースに定期的に投げると説明しましたが、どれだけ頻繁に投げるかの設定はデータベースのコネクションの設定で行います。
詳しくはこちらの公式ドキュメントをご確認ください:PDTとデータグループのメンテナンススケジュール
max_cache_age
max_cache_age
パラメータは、datagroup
のサブパラメータのもう一つです。
max_cache_age: 24 hours
のように"○秒"、"○分"、"○時間"と期間を定めて古いキャッシュが使われることを防ぎます。
sql_trigger
の設定だけで足りる気がするかもしれませんが、もしもデータの更新があったのにsql_trigger
の値が変わらなかった場合の保険として、max_cache_age
も併せて設定することを推奨しています。
persist_withの設定
設定したデータグループをモデルまたはExploreに適用させるのにpersist_with
パラメータを設定します。
モデルとExploreの両方にデータグループを定義した場合、Exploreで定義されたデータグループが優先されます。
キャッシュを使用したくない場合
キャッシュを使用せずにクエリを実行したいことがあると思います。状況に合わせてキャッシュを使用せずに直接データベースへクエリを投げる方法をご紹介します。
Exploreまたはダッシュボード画面で
まずは、データグループでの設定を変更せずに、Exploreやダッシュボードの画面からキャッシュを利用せずにクエリを実行する方法をご紹介します。
Explore
Runボタン横のギアマークをクリックすると、Clear Cache & Refleshが表示されるので選択すると、キャッシュを利用せずに結果を出すことができます。
ちなみに、クエリ結果がデータベースに問い合わせた結果なのか、キャッシュからの結果なのかは、結果が返ってきた後のRunボタン横に表示されます。
データベースからの場合
上図の通り、500 rows・0.7s・just now
何行が何秒でたった今 といった表示の場合はデータベースに問い合わせた結果です。
キャッシュからの場合
上図の通り、500 rows・from cache・1m ago
何行がキャッシュから何分前に とキャッシュからと明示的に教えてくれます。
ダッシュボード
ダッシュボードもRun横のギアマークをクリックすると、Clear Cache & Refleshが表示されるので選択すると、キャッシュではなく再びデータベースへクエリを投げてくれます。
ダッシュボードの結果がデータベースに問い合わせた結果なのかどうかも、Run横の表示で確認することができます。しかし、Exploreとはちょっと勝手が異なります。
データベースからの場合
Run横にjust now
とのみ表示されます。
キャッシュからの場合
Exploreとは違ってnm ago
と何分前にクエリが実行されたのかのみ表示されます。Runを押さなくても時間が経てばここの数字は自動で更新されました。(実際に目で確認するまで画面をじーっと見つめました。)
LookMLの設定で強制的にキャッシュを利用しないようにする
全クエリ毎回データベースへクエリを投げるためには、persist_for
パラメータを以下の通り定義します。
# model persist_for: "0 seconds" # explore explore: explore_name { persist_for: "0 seconds" }
persist_for
パラメータは、モデルやExploreのキャッシュの保持時間を設定するパラメータです。この設定を0秒にすることでキャッシュは0秒間保持されるということになるので、実行されたクエリは毎回データベースへ投げられるという仕組みです。
名前はデータグループを適用するpersist_with
パラメータと似ていて、役割はmax_cache_age
パラメータと似ているという非常にややこしいパラメータです。
慣れてしまえば問題ないのですが、個人的には最初は、LookerIDEのサジェストを思いきり利用して、persist_for
を選択すると文字列を入れる""
(ダブルクォート)が入力されて、persist_with
を選択するとダブルクォートが出てこないというので判断していました。
また、datagroup
パラメータのサブパラメータにはpersist_for
がないので、そもそもサジェストの選択を間違えることはないです。
まとめ
Lookerのキャッシュについてきちんと理解できたでしょうか?
何も設定していない状態でも1時間はキャッシュが効いてしまっているというのがミソと自分では思っています。
こちらのLookerのパフォーマンスを最適化するためのベストプラクティスを紹介する記事でも、ETLの処理に合わせてデータグループを設定して、最大限Lookerのキャッシュを利用することが推奨されています。
少なくとも初期モデルをユーザーにデプロイする際にはデータグループを設定しておくといいでしょう!